#ifndef POINTER_H
#define POINTER_H

template <class T> class Pointer {
	public:
		explicit Pointer(T* p = 0) {
			if (p) data = new Data(p);
			else data = 0;
		}
		Pointer(const Pointer& snd) {
			acquire(snd.data);
		}
		
		//Pointer() : data(NULL) { }
		
		Pointer& operator=(const Pointer& r) {
			if (this != &r) {
				release();
				acquire(r.data);
			}
			return *this;
		}
		
		~Pointer() {
			release();
		}
		
		T* operator->() const {
			return data->ptr;
		}
		
		T& operator*() const {
			return *data->ptr;
		}
		
		void set(T* p) {
			if (data) {
				delete data->prt;
				data->ptr = p;
			}
			else {
				data = new Data(p);
			}
		}
		
		T* get() const { return data ? data->ptr : 0; }
		
		bool isNull() { return data ? data->ptr == 0 : true; }
		
	private:
		struct Data {
			Data(T* p = 0, unsigned int _counter = 1) : ptr(p), counter(_counter) { }
			T* ptr;
			unsigned int counter;
		}* data;
		
		void acquire(Data* c) {
			data = c;
			if (c) ++c->counter;
		}
		
		void release() {
			if (data) {
				if (--data->counter == 0) {
					delete data->ptr;
					delete data;
				}
				data = 0;
			}
		}
};

#endif
